<style>
	.container {
		width: 100%;
		max-width:initial;
		padding: 0 40px;
		> .row{
			margin: 0;
			> .col{
				padding: 0;
			}
		}
	}

	.container,
	#nodes_rows * {
		-webkit-transition: all 400ms ease-in-out;
		-moz-transition: all 400ms ease-in-out;
		-o-transition: all 400ms ease-in-out;
		-ms-transition: all 400ms ease-out;
		transition: all 400ms ease-out;
	}

	#nodes_rows td:first-child,
	#nodes_rows td:nth-child(9) {
		text-align: left;
	}

	.card-content h6 {
		margin-bottom: 0.49rem;
	}

	@media only screen and (max-width: 992px) {
		.container {
			padding: 0 10px;
		}
	}
</style>
<div style="height: 10px; clear: both;"></div>
<div class="row">
	<div class="col s12">
		<div class="row">
			<div class="col s12 m12 l2">
				<div class="card hoverable">
					<div class="card-content">
						<div class="d-flex no-block">
							<div class="m-r-12">
								<span>Last block height</span>
								<h6 class="light-blue-text text-darken-4"><strong id="commonHeight"></strong></h6>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="col s12 m12 l5">
				<div class="card hoverable">
					<div class="card-content">
						<div class="d-flex no-block">
							<div class="m-r-12">
								<span>Last block hash</span>
								<h6><strong style="font-family: Inconsolata, monospace; word-wrap: break-word; line-height: 90%;" id="commonHash" class="light-blue-text text-darken-4"></strong></h6>
							</div>
						</div>
					</div>
				</div>
			</div>

			<div class="col s12 m12 l2">
				<div class="card hoverable">
					<div class="card-content">
						<div class="d-flex no-block">
							<div class="m-r-12">
								<span>Network hashrate</span>
								<h6 class="light-blue-text text-darken-4"><strong id="networkHashrate"></strong></h6>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="col s12 m12 l2">
				<div class="card hoverable">
					<div class="card-content">
						<div class="d-flex no-block">
							<div class="m-r-12">
								<span>Next difficulty</span>
								<h6 class="light-blue-text text-darken-4"><strong id="networkDifficulty"></strong> (<span id="networkDifficultyRounded"></span>) </h6>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="col s12 m12 l1">
				<div class="card hoverable">
					<div class="card-content">
						<div class="d-flex no-block">
							<div class="m-r-12">
								<span>Nodes</span>
								<h6 class="light-blue-text text-darken-4"><strong id="totalNodes"></strong></h6>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>
<div class="row">
	<div class="col s12">
		<div class="card hoverable">
			<div class="card-content">
				<div class="row">
					<div class="col s12 table-responsive">
						<table id="nodesTable" class="highlight centered sortable">
							<thead>
								<tr>
									<th><i class="fas fa-network-wired"></i>&nbsp;Nodes</th>
									<th class="sorttable_numeric"><i class="fas fa-list-ol"></i>&nbsp;Height</th>
									<th class="sorttable_numeric"><i class="fas fa-hashtag"></i>&nbsp;Hash</th>
									<th class="sorttable_numeric"><i class="fas fa-bars"></i>&nbsp;Known</th>
									<th class="sorttable_numeric"><i class="fas fa-unlock-alt"></i>&nbsp;Difficulty</th>
									<th class="sorttable_numeric"><i class="fas fa-plug"></i>&nbsp;RPC</th>
									<th class="sorttable_numeric"><i class="fas fa-arrow-circle-down"></i>&nbsp;INC</th>
									<th class="sorttable_numeric"><i class="fas fa-arrow-circle-up"></i>&nbsp;OUT</th>
									<th class="sorttable_numeric"><i class="fas fa-flag"></i>&nbsp;Version</th>
									<th><i class="fas fa-clock"></i>&nbsp;Start time</th>
									<th><i class="fas fa-hourglass-end"></i>&nbsp;Uptime</th>
									<th><i class="fas fa-donate"></i>&nbsp;Fee</th>
								</tr>
							</thead>
							<colgroup width="300"></colgroup>
							<colgroup width="100"></colgroup>
							<colgroup width="500"></colgroup>
							<tbody id="nodes_rows"></tbody>
						</table>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>
<div class="row">
	<div class="col s12">
		<div class="card hoverable">
			<div class="card-content">
				<div class="row">
					<div class="col s12">
						<table>
							<tbody>
								<tr>
									<td>
										<div class="input-field">
											<input id="node_address" name="node" type="url" class="validate">
											<label for="node_address">Node URL</label>
										</div>
									</td>
									<td width="180">
										<button id="submit_node_button" class="btn light-blue darken-3" href="#">
											Submit&nbsp;node&nbsp;<i class="material-icons right">send</i>
										</button>
									</td>
								</tr>
							</tbody>
						</table>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<script src="js/sorttable.js"></script>
<script src="js/moment.min.js"></script>
<script>
	function cmp(a, b) {
		return a - b;
	}

	function mode(array) {
		if (array.length == 0)
			return null;
		var modeMap = {};
		var maxEl = array[0],
			maxCount = 1;
		for (var i = 0; i < array.length; i++) {
			var el = array[i];
			if (modeMap[el] == null)
				modeMap[el] = 1;
			else
				modeMap[el]++;
			if (modeMap[el] > maxCount) {
				maxEl = el;
				maxCount = modeMap[el];
			}
		}
		return maxEl;
	}
	
	window.commonHeight;
	window.commonHash;
	window.commonVersion;
	window.commonDifficulty;
	nodesStat = [];
	Heights = [];
	Hashes = [];
	nextDifficulties = [];
	Versions = [];
	totalNodes = 0;
	lastReward = 0;
	var it = -1;

	currentPage = {
		destroy: function () {},
		init: function () {

			getNodes()

			updateStats();
		},
		update: function () {
			updateStats();
		}
	};
	
	$('#submit_node_button').click(function (e) {
		var url = document.getElementById('node_address').value;
		submitNode(url);
		e.preventDefault();
	});

	var nodesRefreshed = 0;

	function getNodes() {
		var jqxhr = $.getJSON( "api/nodes.json", function() {
		
		})
		.done(function(data) {
			console.log( "Got nodes..." );
			for (var key in data) {
				if (data.hasOwnProperty(key)) {
					var item = data[key];
					nodesStat.push(item);
				}
			}

			$.when(
				initNodes()
			).then(function () {

				setTimeout(function () {
					setFees();
				}, 100);

			});

		})
		.fail(function() {
			console.log( "Error getting list of nodes..." );
		})
		.always(function() {
			console.log( "Complete getting list of nodes..." );
		});	
	}

	function updateStats() {
		updateText('networkHashrate', getReadableHashRateString(lastStats.difficulty / blockTargetInterval) + '/sec');
		updateText('networkDifficultyRounded', getReadableDifficultyString(lastStats.difficulty, 2).toString());
	}

	function initNodes() {
		var now = new Date();
		nodesStat.forEach(function (node) {

			var url = node;
			var purl;
			if (window.location.protocol == 'https:') {
				var pattern = /^((https):\/\/)/;
				if (!pattern.test(url)) {
					purl = '/api/?mode=get&url=' + url;
				} else {
					purl = url;
				}
			} else {
				purl = url;
			}

			var nurl = new URL(url);
			var nname = nurl.hostname;

			$.ajax({
				url: purl + '/getinfo',
				dataType: 'json',
				type: 'GET',
				cache: 'false'
			}).done(function (data, success) {

				var nodeHeight = data.height - 1; // we need last block here not blockchain height
				var nodeHash = "—";
				if (typeof data.top_block_hash !== "undefined") {
					nodeHash = data.top_block_hash;
					Hashes.push(nodeHash);
				}
				Heights.push(nodeHeight);
				var dateTime;
				var uptime = "—";
				var startTime = "—";
				if (!isNaN(data.start_time)) {
					startTime = formatDate(data.start_time);
					dateTime = new Date(data.start_time * 1000).toISOString();
					uptime = moment.duration(moment(now).diff(moment(dateTime))).humanize();
				}
				var rpcCount = "—";
				if (!isNaN(data.rpc_connections_count)) {
					rpcCount = data.rpc_connections_count;
				}
				$('#nodes_rows').append('<tr><td id=node-' + nname + '><a target=blank href="' + url +
					'/getinfo">' + nname + '</a></td><td class="height" id=nodeHeight-' + nname + '>' +
					nodeHeight + '</td><td class="break-word hash" id=nodeHash-' + nname + '>' +
					nodeHash + '</td><td id=known-' + nname + '>' + data.last_known_block_index +
					'</td><td class="difficulty" id=diff-' + nname + '>' + data.difficulty +
					'</td><td id=rpc-' + nname + '>' + rpcCount + '</td><td id=inc-' +
					nname + '>' + data.incoming_connections_count + '</td><td id=out-' + nname + '>' + data
					.outgoing_connections_count + '</td><td class="version" id=ver-' + nname + '>' + data
					.version + '</td><td class="date-time">' + startTime +
					'</td><td id="uptime-'+ nname +'">' + uptime + '</td>' +
					'<td id="fee-'+ nname +'">' + "-" + '</td></tr>');
				Versions.push(data.version);
				nextDifficulties.push(parseInt(data.difficulty));
				totalNodes++;
				nodesRefreshed++;
				updateText('totalNodes', totalNodes);

				setCommons();
			});
		});
	}

	function setFees() {
		console.log("Getting nodes fees...");

		nodesStat.forEach(function (node) {
			var url = node;
			var purl;
			if (window.location.protocol == 'https:') {
				var pattern = /^((https):\/\/)/;
				if (!pattern.test(url)) {
					purl = '/api/?mode=get&url=' + url;
				} else {
					purl = url;
				}
			} else {
				purl = url;
			}

			var nurl = new URL(url);
			var nname = nurl.hostname;

			$.ajax({
				url: purl + '/feeaddress',
				dataType: 'json',
				type: 'GET',
				cache: 'false'
			}).done(function (data, success) {
				updateText('fee-' + nname, "free");
				if (data.fee_address !== "") {
					updateText('fee-' + nname, "0.25%");
				}
				if (!isNaN(data.fee_amount)) {
					var nodeFee = data.fee_amount;
					console.log("fee for " + nname + ": " + nodeFee);
					updateText('fee-' + nname,  parseFloat(getReadableCoins(nodeFee, 12, true)).toString() + "\xa0KRB");
				}
			}).fail(function() {
				console.log( "Error getting node's fee: " + nname );
			});
		});
	}

	// Refresh
	setInterval(function () {
		nodesRefreshed = 0;
		totalNodes = 0;
		nextDifficulties = [];
		Versions = [];
		Heights = [];
		Hashes = [];
		it = -1;
		var now = new Date();
		nodesStat.forEach(function (node) {

			var url = node;
			var purl;
			if (window.location.protocol == 'https:') {
				var pattern = /^((https):\/\/)/;
				if (!pattern.test(url)) {
					purl = '/api/?mode=get&url=' + url;
				} else {
					purl = url;
				}
			} else {
				purl = url;
			}

			var nurl = new URL(url);
			var nname = nurl.hostname;

			$.ajax({
				url: purl + '/getinfo',
				dataType: 'json',
				type: 'GET',
				cache: 'false',
				success: function(data) {
					var nodeHeight = data.height - 1; // we need last block here not blockchain height
					var nodeHash = "—";
					if (typeof data.top_block_hash !== "undefined") {
						nodeHash = data.top_block_hash;
						Hashes.push(nodeHash);
					}
					Heights.push(nodeHeight);
					var dateTime;
					var uptime = "—";
					if (!isNaN(data.start_time)) {
						dateTime = new Date(data.start_time * 1000).toISOString();
						agostring = $.timeago(dateTime);
						uptime = moment.duration(moment(now).diff(moment(dateTime))).humanize();
					}
					var rpcCount = "—";
					if (!isNaN(data.rpc_connections_count)) {
						rpcCount = data.rpc_connections_count;
					}
					updateText('nodeHeight-' + nname, nodeHeight);
					updateText('nodeHash-' + nname, nodeHash);
					updateText('known-' + nname, data.last_known_block_index);
					updateText('diff-' + nname, data.difficulty);
					updateText('rpc-' + nname, rpcCount);
					updateText('inc-' + nname, data.incoming_connections_count);
					updateText('out-' + nname, data.outgoing_connections_count);
					updateText('ver-' + nname, data.version);
					updateText('uptime-' + nname, uptime);
					Versions.push(data.version);
					nextDifficulties.push(parseInt(data.difficulty));
					totalNodes++;
					nodesRefreshed++;
					updateText('totalNodes', totalNodes);

					setCommons();
				}
			});
		});

	}, refreshDelay);

	$(function () {
		$('[data-toggle="tooltip"]').tooltip();
	});

	var xhrGetBlocks;

	function setCommons() {
		commonHeight = mode(Heights);
		commonHash = mode(Hashes);
		commonVersion = mode(Versions);
		commonDifficulty = mode(nextDifficulties);
		updateText('networkDifficulty', commonDifficulty.toString());
		updateText('commonHeight', commonHeight.toString());
		updateText('commonHash', commonHash);

		setTimeout(function () {
			highlightOutliers();
		}, 100);
	}

	function highlightOutliers() {
		var nodeRows = $('#nodes_rows').children();
		for (var i = 0; i < nodeRows.length; i++) {
			var row = $(nodeRows[i]);
			row.removeClass("yellow lighten-5").removeClass("red lighten-5");
			row.find('.version').removeClass("yellow-text text-darken-4");
			row.find('.difficulty').removeClass("red-text text-darken-4");
			row.find('.height').removeClass("red-text text-darken-4");
			row.find('.hash').removeClass("red-text text-darken-4");

			var nodeDiff = row.find('.difficulty').text();
			if (nodeDiff != commonDifficulty) {
				row.removeClass("red lighten-5").addClass("yellow lighten-5");
				row.find('.difficulty').addClass("red-text text-darken-4");
			}

			var nodeHeight = row.find('.height').text();
			var nodeHash = row.find('.hash').text();
			if (nodeHeight != commonHeight || nodeHash != commonHash) {
				row.addClass("yellow lighten-5");
			}
			if (nodeHeight != commonHeight && nodeHash != commonHash) {
				row.removeClass("yellow lighten-5").addClass("red lighten-5");
			}
			var nodeVersion = row.find('.version').text();
			if (nodeVersion != commonVersion) {
				row.find('.version').addClass("yellow-text text-darken-4");
			}

			if (nodeHeight != commonHeight) {
				row.find('.height').addClass("red-text text-darken-4");
			}
			if (nodeHash != commonHash) {
				row.find('.hash').addClass("red-text text-darken-4");
			}
		}
	}

	function submitNode(url) {
	$.ajax({
			type: 'POST',
			data: { 'node': url },
			url: 'api/submit_node.php',
			dataType: 'json',
			//async: 'false',
			cache: 'false',
			success: function(data) {
				M.toast({html: data.result});
			},
			error: function() {
				M.toast({html: "Error submitting node"});
			}
		});

	}
</script>